/**
 * 数据管理抽象层
 */
#pragma once

#include "EventList.h"
#include "EventString.h"

#include <time.h>

/* 数据管理器操作方法返回枚举 */
typedef enum
{
	/* 数据管理器操作成功 */
	DATA_MANAGER_SUCCESS = 0,
	/* 用户已存在 */
	DATA_MANAGER_USER_ALREADY_EXISTS_ERROR = 1,
	/* 空对象错误 */
	DATA_MANAGER_NULL_OBJECT_ERROR = 2,
	/* 数据管理器未初始化 */
	DATA_MANAGER_NOT_INITIALIZE_ERROR = 3,
	/* 事件组不存在 */
	DATA_MANAGER_GROUP_NOT_EXIST_ERROR = 4,
	/* 用户尚不存在：未注册 */
	DATA_MANAGER_USER_NOT_REGISTER_ERROR = 5,
	/* 用户验证错误 */
	DATA_MANAGER_USER_VERIFY_FAILED = 6,
	/* 对事件组的操作被拒绝：无权限 */
	DATA_MANAGER_GROUP_PERMISSION_DENIED,
	/* 事件组全局不可写 */
	DATA_MANAGER_GROUP_GLOBAL_CAN_NOT_WRITE,
	/* 本用户在事件组中不可写 */
	DATA_MANAGER_GROUP_CAN_NOT_WRITE,
	/* 事件表不存在 */
	DATA_MANAGER_EVENT_TABLE_NOT_EXIST_ERROR,
	/* 事件条目不存在 */
	DATA_MANAGER_EVENT_ITEM_NOT_EXIST_ERROR,
	/* 用户尚未登陆 */
	DATA_MANAGER_USER_NOT_LOGON,
	/* 用户不在该事件组中 */
	DATA_MANAGER_USER_NOT_BELONG_GROUP,
	/* 用户已存在于该组中 */
	DATA_MANAGER_USER_EXISTED_IN_GROUP,
	/* 不可退出默认事件组 */
	DATA_MANAGER_CAN_NOT_QUIT_DEFAULT_GROUP,
	//
	DATA_MANAGER_END,
} DataManagerRet;

/* 数据管理器对象 */
typedef struct _DataManager DataManager;
#define DATA_MANAGER(any) ((DataManager *)any)

extern DataManager *data_manager_new(void);

/**
 * @brief 设置数据管理库的工作目录，初始化前必做项
 */
extern void data_manager_set_base_path(DataManager *self,
				       const char  *base_path);

/**
 * @brief 根据 onlineID 获取用户 UserID。返回用户的 UserID
 * @return 若用户不在线则将返回 0
 */
extern euint32 data_manager_get_uid_from_oid(DataManager *self,
					     euint64	  online_id);

/**
 * @brief 根据用户手机号获取用户 UserID
 * @return 若用户不存在则返回 0
 */
extern euint32 data_manager_get_uid_from_phone(DataManager *self,
					       euint64	    phone);

/**
 * @brief 根据用户 UserID 获取手机号
 */
extern euint64 data_manager_get_phone_from_uid(DataManager *self,
					       euint32	    user_id);

/**
 * @brief 初始化数据库实例，并返回是否初始化是否成功
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_NOT_INITIALIZE_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_init(DataManager *self);

/**
 * @brief 向数据库中注册一条用户信息
 * @param  EventString : 注意：将会增加引用一次。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_NOT_INITIALIZE_ERROR，
 *         DATA_MANAGER_USER_ALREADY_EXISTS_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_register(DataManager *self, euint64 phone,
				 EventString *user_name, EventString *password);

/**
 * @brief 验证用户的手机号与密码是否正确，不会增加 password 的引用计数
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_USER_VERIFY_FAILED，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_verify_user(DataManager *self, euint64 phone,
				    const EventString *password);

/**
 * @brief 验证用户保持状态。客户端 30 天重登陆内无需验证码登陆，
 *        5 分钟内与服务器建立连接便可维持在线状态，超过 5 分钟
 *        则需要重新登陆。
 * @return 0: 用户在线中，1: 用户不在线，需要重新登陆，2:
 *         用户不在保持表中，需要结合验证码登陆
 */
extern int data_manager_verify_logon_state(DataManager *self, euint64 oid);

/**
 * @brief 强制刷新保持条目的状态
 * @return 0: 成功，1: 未找到相关保持条目，2: 空对象错误
 */
extern int data_manager_flush_online_state(DataManager *self,
					   euint64	online_id);

/**
 * @brief 新增一条用户的在线记录
 * @return 返回新的 onlineID，并传送给客户端保存
 */
extern euint64 data_manager_add_keep_item(DataManager *self, euint32 user_id);

/**
 * @brief 强制修改用户密码。注意，EventString 对象将被引用！
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_user_password(DataManager *self, euint32 user_id,
					     EventString *modify_password);

/**
 * @brief 强制修改用户名。注意，EventString 对象将被引用！
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_user_name(DataManager *self, euint32 user_id,
					 EventString *modify_user_name);

/**
 * @brief 修改事件组名。请注意，EventString 对象将被引用
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_group_name(DataManager *self,
					  euint32      operator_uid,
					  euint32      group_id,
					  EventString *group_name);

/**
 * @brief 修改事件条目。请注意，EventString 对象将被引用！
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_GLOBAL_CAN_NOT_WRITE，
 *         DATA_MANAGER_GROUP_CAN_NOT_WRITE，
 *         DATA_MANAGER_EVENT_TABLE_NOT_EXIST_ERROR，
 *         DATA_MANAGER_EVENT_ITEM_NOT_EXIST_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_event_item(DataManager *self,
					  euint32 creator_uid, euint32 group_id,
					  euint32 event_id, time_t end_time,
					  EventString *event_name,
					  EventString *event_describe,
					  bool	       is_important);

/**
 * @brief 修改事件组的总可写标志。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_group_can_write_flag(DataManager *self,
						    euint32	 operator_id,
						    euint32	 group_id,
						    bool	 can_write);

/**
 * @brief 修改某位用户在事件组内的可写标志。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_member_can_write_flag(DataManager *self,
						     euint32	  operator_id,
						     euint32	  group_id,
						     euint32	  modify_uid,
						     bool	  can_write);

/**
 * @brief 修改事件组的可加入标志。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_modify_group_can_join_flag(DataManager *self,
						   euint32	operator_id,
						   euint32	group_id,
						   bool		can_join);

/**
 * @brief 创建事件组。注意！EventString 对象将被引用一次。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         无错误则返回 GroupID，需要进行 euint32 的转换
 */
extern int data_manager_create_group(DataManager *self, euint32 operator_uid,
				     EventString *group_name, bool g_can_write,
				     bool can_join);

/**
 * @brief 创建一条新的事件条目。请注意！EventString 对象将被引用一次
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_GLOBAL_CAN_NOT_WRITE，
 *         DATA_MANAGER_GROUP_CAN_NOT_WRITE，
 *         新建的 EventID
 */
extern int data_manager_create_event(DataManager *self, euint32 operator_uid,
				     euint32 group_id, time_t end_time,
				     EventString *event_name,
				     EventString *event_describe,
				     bool	  is_important);

/**
 * @brief 添加用户到事件组。
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_add_user_to_group(DataManager *self,
					  euint32      operator_uid,
					  euint32      addtion_uid,
					  euint32      group_id);

/**
 * @brief 刷新保持条目
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_USER_NOT_LOGON，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_flush_keep_state(DataManager *self, euint64 online_id);

/**
 * @brief 移除事件组
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_remove_group(DataManager *self, euint32 operator_uid,
				     euint32 will_remove_gid);

/**
 * @brief 从事件组中移除某位成员
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_USER_NOT_BELONG_GROUP，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_remove_member_from_group(DataManager *self,
						 euint32      operator_uid,
						 euint32      group_id,
						 euint32      will_remove_uid);

/**
 * @brief 从事件组中移除一条事件条目
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_CAN_NOT_WRITE，
 *         DATA_MANAGER_EVENT_ITEM_NOT_EXIST_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_remove_event_from_group(DataManager *self,
						euint32	     operator_uid,
						euint32	     group_id,
						euint32	     will_remove_eid);

/**
 * @brief 处理用户退出事件组的操作
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_USER_NOT_BELONG_GROUP，
 *         DATA_MANAGER_USER_NOT_REGISTER_ERROR，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_handle_user_quit_from_group(DataManager *self,
						    euint32	 user_id,
						    euint32	 group_id);

/**
 * @brief 拉取用户的所有事件条目
 * @return EventList * / NULL
 */
extern EventList *data_manager_user_fetch_all_event(DataManager *self,
						    euint32	 user_id);

/**
 * @brief 拉取用户加入的所有事件组信息
 * @return EventList * / NULL
 */
extern EventList *data_manager_user_fetch_all_group_info(DataManager *self,
							 euint32      user_id);

/**
 * @brief 用户加入事件组
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_USER_EXISTED_IN_GROUP，
 *         DATA_MANAGER_SUCCESS
 */
extern int data_manager_user_join_group(DataManager *self, euint32 operator_uid,
					euint32 group_id);
extern EventString *data_manager_dup_user_joined_group_name(DataManager *self);

/**
 * @brief 获取用户名
 */
extern EventString *data_manager_dup_user_name(DataManager *self,
					       euint32	    user_id);

/**
 * @brief 拉取组内所有用户的信息
 * @return DATA_MANAGER_NULL_OBJECT_ERROR，
 *         DATA_MANAGER_GROUP_NOT_EXIST_ERROR，
 *         DATA_MANAGER_GROUP_PERMISSION_DENIED，
 *         DATA_MANAGER_SUCCESS
 */
extern EventList *data_manager_fetch_all_memeber_info(DataManager *self,
						      euint32	   operator_uid,
						      euint32	   group_id);

/**
 * @brief 获取操作结果
 */
extern DataManagerRet data_manager_get_result(DataManager *self);
